#ifndef GameLuaCallerWrap_h
#define GameLuaCallerWrap_h
#include "lua.hpp"
#include "render_v1.h"

namespace hxe
{
    class GameLuaCallerWrap
    {
    private:
        static int getSceneRoot(lua_State *L)
        {
            Transform* r = SceneInst->getRoot();
            if (r == nullptr)
            {
                return 0;
            }
            HLuaInst->push(r, TransformWrap::metaRef);
            return 1;
        }

        static int createModel(lua_State *L)
        {
            const char* path = lua_tostring(L, 1);
            const char* name = lua_tostring(L, 2);
            GameObject* obj = Creator::createModel(path, Vector3(0.0f, 0.0f, 0.0f), name);
            SceneInst->addGameObject(obj);
            HLuaInst->push(obj, GameObjectWrap::metaRef);
            return 1;
        }

        static int createPlane(lua_State *L)
        {
            float width = (float)lua_tonumber(L, 1);
            float height = (float)lua_tonumber(L, 2);
            int horizontalCount = (int)lua_tointeger(L, 3);
            int verticalCount = (int)lua_tointeger(L, 4);

            GameObject* obj = Creator::createPlane(width, height, horizontalCount, verticalCount);
            SceneInst->addGameObject(obj);
            HLuaInst->push(obj, GameObjectWrap::metaRef);
            return 1;
        }

        static int createCube(lua_State *L)
        {
            float length = (float)lua_tonumber(L, 1);
            float width = (float)lua_tonumber(L, 2);
            float height = (float)lua_tonumber(L, 3);

            GameObject* obj = Creator::createCube(length, width, height);
            SceneInst->addGameObject(obj);
            HLuaInst->push(obj, GameObjectWrap::metaRef);
            return 1;
        }

        static int createRobot(lua_State *L)
        {
            float r = (float)lua_tonumber(L, 1);
            float g = (float)lua_tonumber(L, 2);
            float b = (float)lua_tonumber(L, 3);
            float a = (float)lua_tonumber(L, 4);

            GameObject* obj = Creator::createRobot(Color(r, g, b, a));
            SceneInst->addGameObject(obj);
            HLuaInst->push(obj, GameObjectWrap::metaRef);
            return 1;
        }

        static int createSphere(lua_State *L)
        {
            float radius = (float)lua_tonumber(L, 1);
            unsigned int row = (unsigned int)lua_tointeger(L, 2);
            unsigned int col = (unsigned int)lua_tointeger(L, 2);

            GameObject* obj = Creator::createSphere(radius, row, col);
            SceneInst->addGameObject(obj);
            HLuaInst->push(obj, GameObjectWrap::metaRef);
            return 1;
        }

        static int createImage(lua_State *L)
        {
            const char* path = lua_tostring(L, 1);
            float width = (float)lua_tonumber(L, 2);
            float height = (float)lua_tonumber(L, 3);

            GameObject* obj = Creator::createImage(path, width, height);
            SceneInst->addGameObject(obj);
            HLuaInst->push(obj, GameObjectWrap::metaRef);
            return 1;
        }
        

    public:
        static int metaRef;
        static int loadWrap(lua_State *L)
        {
            lua_newtable(L);

            lua_pushstring(L, "GetSceneRoot");
            lua_pushcclosure(L, getSceneRoot, 0);
            lua_rawset(L, -3);

            lua_pushstring(L, "CreateModel");
            lua_pushcclosure(L, createModel, 0);
            lua_rawset(L, -3);

            lua_pushstring(L, "CreatePlane");
            lua_pushcclosure(L, createPlane, 0);
            lua_rawset(L, -3);

            lua_pushstring(L, "CreateCube");
            lua_pushcclosure(L, createCube, 0);
            lua_rawset(L, -3);

            lua_pushstring(L, "CreateSphere");
            lua_pushcclosure(L, createSphere, 0);
            lua_rawset(L, -3);

            lua_pushstring(L, "CreateRobot");
            lua_pushcclosure(L, createRobot, 0);
            lua_rawset(L, -3);

            lua_pushstring(L, "CreateImage");
            lua_pushcclosure(L, createImage, 0);
            lua_rawset(L, -3);

            lua_pushvalue(L, -1);
            lua_setglobal(L, "GameLuaCaller");
            metaRef = luaL_ref(L, LUA_REGISTRYINDEX);

            return 0;
        }
    };

    int GameLuaCallerWrap::metaRef = 0;
};

#endif